import gbk from './gbk.js';

const commands = {
	LF: [0x0a],
	FS: [0x1c],
	FF: [0x0c],
	GS: [0x1d],
	DLE: [0x10],
	EOT: [0x04],
	NUL: [0x00],
	ESC: [0x1b],
	EOL: '\n',
	FEED_CONTROL_SEQUENCES:{
		CTL_LF: [0x0a],   // Print and line feed
		CTL_GLF: [0x4a, 0x00],   // Print and feed paper (without spaces between lines)
		CTL_FF: [0x0c],   // Form feed
		CTL_CR: [0x0d],   // Carriage return
		CTL_HT: [0x09],   // Horizontal tab
		CTL_VT: [0x0b]   // Vertical tab
	},
	CHARACTER_SPACING:{
		CS_DEFAULT: [0x1b, 0x20, 0x00],
		CS_SET: [0x1b, 0x20]
	},
	LINE_SPACING:{
		LS_DEFAULT: [0x1b, 0x32],
		LS_SET: [0x1b, 0x33]
	},
	HARDWARE:{
		HW_INIT: [0x1b, 0x40], // Clear data in buffer and reset modes
		HW_SELECT: [0x1b, 0x3d, 0x01], // Printer select
		HW_RESET: [0x1b, 0x3f, 0x0a, 0x00] // Reset printer hardware
	},
	CASH_DRAWER:{
		CD_KICK_2: [0x1b, 0x70, 0x00], // Sends a pulse to pin 2 []
		CD_KICK_5: [0x1b, 0x70, 0x01] // Sends a pulse to pin 5 []
	},
	MARGINS:{
		BOTTOM: [0x1b, 0x4f], // Fix bottom size
		LEFT: [0x1b, 0x6c], // Fix left size
		RIGHT: [0x1b, 0x51] // Fix right size
	},
	PAPER:{
		PAPER_FULL_CUT: [0x1d, 0x56, 0x00], // Full cut paper
		PAPER_PART_CUT: [0x1d, 0x56, 0x01], // Partial cut paper
		PAPER_CUT_A: [0x1d, 0x56, 0x41], // Partial cut paper
		PAPER_CUT_B: [0x1d, 0x56, 0x42] // Partial cut paper
	},
	TEXT_FORMAT:{
		TXT_NORMAL: [0x1b, 0x21, 0x00], // Normal text
		TXT_2HEIGHT: [0x1b, 0x21, 0x10], // Double height text
		TXT_2WIDTH: [0x1b, 0x21, 0x20], // Double width text
		TXT_4SQUARE: [0x1b, 0x21, 0x30], // Double width & height text
		
		TXT_UNDERL_OFF: [0x1b, 0x2d, 0x00], // Underline font OFF
		TXT_UNDERL_ON: [0x1b, 0x2d, 0x01], // Underline font 1-dot ON
		TXT_UNDERL2_ON: [0x1b, 0x2d, 0x02], // Underline font 2-dot ON
		TXT_BOLD_OFF: [0x1b, 0x45, 0x00], // Bold font OFF
		TXT_BOLD_ON: [0x1b, 0x45, 0x01], // Bold font ON
		TXT_ITALIC_OFF: [0x1b, 0x35], // Italic font ON
		TXT_ITALIC_ON: [0x1b, 0x34], // Italic font ON
		
		TXT_FONT_A: [0x1b, 0x4d, 0x00], // Font type A
		TXT_FONT_B: [0x1b, 0x4d, 0x01], // Font type B
		TXT_FONT_C: [0x1b, 0x4d, 0x02], // Font type C
		
		TXT_ALIGN_LT: [0x1b, 0x61, 0x00], // Left justification
		TXT_ALIGN_CT: [0x1b, 0x61, 0x01], // Centering
		TXT_ALIGN_RT: [0x1b, 0x61, 0x02] // Right justification
	},
	BARCODE_FORMAT:{
		BARCODE_TXT_OFF: [0x1d, 0x48, 0x00], // HRI barcode chars OFF
		BARCODE_TXT_ABV: [0x1d, 0x48, 0x01], // HRI barcode chars above
		BARCODE_TXT_BLW: [0x1d, 0x48, 0x02], // HRI barcode chars below
		BARCODE_TXT_BTH: [0x1d, 0x48, 0x03], // HRI barcode chars both above and below
		
		BARCODE_FONT_A: [0x1d, 0x66, 0x00], // Font type A for HRI barcode chars
		BARCODE_FONT_B: [0x1d, 0x66, 0x01], // Font type B for HRI barcode chars
		
		BARCODE_HEIGHT: function (height) { // Barcode Height [1-255]
		  return [0x1d, 0x68, height];
		},
		BARCODE_WIDTH: function (width) {   // Barcode Width  [2-6]
		  return [0x1d, 0x77, width];
		},
		BARCODE_HEIGHT_DEFAULT: [0x1d, 0x68, 0x64], // Barcode height default:100
		BARCODE_WIDTH_DEFAULT: [0x1d, 0x77, 0x01], // Barcode width default:1
		
		BARCODE_UPC_A: [0x1d, 0x6b, 0x00], // Barcode type UPC-A
		BARCODE_UPC_E: [0x1d, 0x6b, 0x01], // Barcode type UPC-E
		BARCODE_EAN13: [0x1d, 0x6b, 0x02], // Barcode type EAN13
		BARCODE_EAN8: [0x1d, 0x6b, 0x03], // Barcode type EAN8
		BARCODE_CODE39: [0x1d, 0x6b, 0x04], // Barcode type CODE39
		BARCODE_ITF: [0x1d, 0x6b, 0x05], // Barcode type ITF
		BARCODE_NW7: [0x1d, 0x6b, 0x06], // Barcode type NW7
		BARCODE_CODE93: [0x1d, 0x6b, 0x48], // Barcode type CODE93
		BARCODE_CODE128: [0x1d, 0x6b, 0x49] // Barcode type CODE128
	},
	IMAGE_FORMAT:{
		S_RASTER_N: [0x1d, 0x76, 0x30, 0x00], // Set raster image normal size
		S_RASTER_2W: [0x1d, 0x76, 0x30, 0x01], // Set raster image double width
		S_RASTER_2H: [0x1d, 0x76, 0x30, 0x02], // Set raster image double height
		S_RASTER_Q: [0x1d, 0x76, 0x30, 0x03] // Set raster image quadruple
	},
	BITMAP_FORMAT:{
		BITMAP_S8: [0x1b, 0x2a, 0x00],
		BITMAP_D8: [0x1b, 0x2a, 0x01],
		BITMAP_S24: [0x1b, 0x2a, 0x20],
		BITMAP_D24: [0x1b, 0x2a, 0x21]
	},
	GSV0_FORMAT:{
		GSV0_NORMAL: [0x1d, 0x76, 0x30, 0x00],
		GSV0_DW: [0x1d, 0x76, 0x30, 0x01],
		GSV0_DH: [0x1d, 0x76, 0x30, 0x02],
		GSV0_DWDH: [0x1d, 0x76, 0x30, 0x03]
	},
	BEEP:[0x1b, 0x42],
	COLOR:{
		0: [0x1b, 0x72, 0x00], // black
		1: [0x1b, 0x72, 0x01] // red
	}
}

const printerJobs = function() {
	this._queue = Array.from(commands.HARDWARE.HW_INIT);
	this._enqueue = function(cmd) {
		this._queue.push.apply(this._queue, cmd);
	}
};

/**
 * 增加打印内容
 * @param  {string} content  文字内容
 */
printerJobs.prototype.text = function(content) {
	if (content) {
		let uint8Array = gbk.encode(content);
		let encoded = Array.from(uint8Array);
		this._enqueue(encoded);
	}
	return this;
};

/**
 * 打印文字
 * @param  {string} content  文字内容
 */
printerJobs.prototype.print = function(content) {
	this.text(content);
	this._enqueue(commands.LF);
	return this;
};


printerJobs.prototype.printQrcode = function(content) {

	if (content) {
		const cmds = [].concat([27, 97, 1], [29, 118, 48, 0, 30, 0, 240, 0], content, [27, 74, 3], [27, 64]);
		this._enqueue(cmds);	
		this._enqueue(commands.LF);
	}

	return this;
};



/**
 * 打印文字并换行
 * @param  {string}  content  文字内容
 */
printerJobs.prototype.println = function(content = '') {
	return this.print(content + commands.EOL);
};

/**
 * 设置对齐方式
 * @param {string} align 对齐方式 LT/CT/RT
 */
printerJobs.prototype.setAlign = function(align) {
	this._enqueue(commands.TEXT_FORMAT['TXT_ALIGN_' + align.toUpperCase()]);
	return this;
};

/**
 * 设置字体
 * @param  {string} family A/B/C
 */
printerJobs.prototype.setFont = function(family) {
	this._enqueue(commands.TEXT_FORMAT['TXT_FONT_' + family.toUpperCase()]);
	return this;
};

/**
 * 设定字体尺寸
 * @param  {number} width 字体宽度 1~2
 * @param  {number} height 字体高度 1~2
 */
printerJobs.prototype.setSize = function(width, height) {
	if (2 >= width && 2 >= height) {
		this._enqueue(commands.TEXT_FORMAT.TXT_NORMAL);
		if (2 === width && 2 === height) {
			this._enqueue(commands.TEXT_FORMAT.TXT_4SQUARE);
		} else if (1 === width && 2 === height) {
			this._enqueue(commands.TEXT_FORMAT.TXT_2HEIGHT);
		} else if (2 === width && 1 === height) {
			this._enqueue(commands.TEXT_FORMAT.TXT_2WIDTH);
		}
	}
	return this;
};

/**
 * 设定字体是否加粗
 * @param  {boolean} bold
 */
printerJobs.prototype.setBold = function(bold) {
	if (typeof bold !== 'boolean') {
		bold = true;
	}
	this._enqueue(bold ? commands.TEXT_FORMAT.TXT_BOLD_ON : commands.TEXT_FORMAT.TXT_BOLD_OFF);
	return this;
};

/**
 * 设定是否开启下划线
 * @param  {boolean} underline
 */
printerJobs.prototype.setUnderline = function(underline) {
	if (typeof underline !== 'boolean') {
		underline = true;
	}
	this._enqueue(underline ? commands.TEXT_FORMAT.TXT_UNDERL_ON : commands.TEXT_FORMAT.TXT_UNDERL_OFF);
	return this;
};

/**
 * 设置行间距为 n 点行,默认值行间距是 30 点
 * @param {number} n 0≤n≤255
 */
printerJobs.prototype.setLineSpacing = function(n) {
	if (n === undefined || n === null) {
		this._enqueue(commands.LINE_SPACING.LS_DEFAULT);
	} else {
		this._enqueue(commands.LINE_SPACING.LS_SET);
		this._enqueue([n]);
	}
	return this;
};

/**
 * 打印空行
 * @param {number} n
 */
printerJobs.prototype.lineFeed = function(n = 1) {
	return this.print(new Array(n).fill(commands.EOL).join(''));
};


/**
 * 设置放大倍数
 * @param x 0-7 字符宽放大倍数
 * @param y 0-7 字符高放大倍数
 */
printerJobs.prototype.setCharacterMultiple = function ( x,  y) {
  this._enqueue([0x1d, 0x21]);
  if (0 <= x && x <= 7 && 0 <= y && y <= 7) {
    var cmd = x * 16 + y;
    this._enqueue([cmd]);
  }
  return this;
};

 /**
  *  * 打印二维码
  * @param content 条码数据
  * @param barcodeType 条码类型：
  * 0：PDF417， 1：DATAMATRIX ， 2：QRCODE。
  * @param param1，param2，param3  条码参数：
  * 三个参数表示不同的意思：
  * 1. PDF417
  * param1：表示每行字符数，1<=n<=30。
  * param2：表示纠错等级，0<=n<=8。
  * param3：表示纵向放大倍数。
  * 2. DATAMATRIX
  * param1：表示图形高，0<=n<=144(0:自动选择)。
  * param2：表示图形宽，8<=n<=144(param1 为 0时,无效)。
  * param3：表示纵向放大倍数。
  * 3. QRCODE
  * param1：表示图形版本号，1<=n<=30(0:自动选择)。
  * param2：表示纠错等级，n = 76,77,81,72(L:7%,M:15%,Q:25%,H:30%)。
  * param3：表示纵向放大倍数。
  *
  */
printerJobs.prototype.printQrcode = function (content, barcodeType, param1, param2, param3) {
  var str = content;
  var length = str.replace(/[^\u0000-\u00ff]/g, "aa").length;
  this._enqueue([0x1d,0x5a]);
  this._enqueue([barcodeType]);
  this._enqueue([0x1b, 0x5a]);
  this._enqueue([param1]);
  this._enqueue([param2]);
  this._enqueue([param3]);
  this._enqueue([length%256]);
  this._enqueue([length/256]);
  this.print(content);
  return this;
};

printerJobs.prototype.queryStatus = function () {
  this._enqueue([0x10, 0x04,0x02]);
  return this;
};

/**
 * 清空任务
 */
printerJobs.prototype.clear = function () {
  this._queue = Array.from(commands.HARDWARE.HW_INIT);
  return this;
};

/**
 * 返回ArrayBuffer
 */
printerJobs.prototype.buffer = function () {
  return new Uint8Array(this._queue).buffer;
};


/**
 * CPCL打印
 */

/**
 * 设置标签宽高 必须在开头设置 
 * width:80mm 为576；58mm为384
 */
printerJobs.prototype.label_set_page = function (width,height) {
  var content= "! 0 200 200 " + height + " 1\r\nPAGE-WIDTH " + width + "\r\n";
  this.text(content);
  return this;
};

/**
 * 打印表格
 * lineWidth:边框线条宽度0-1
 * top_left_x:左上角X坐标
 * top_left_y:左上角Y坐标
 * bottom_right_x:右下角X坐标
 * bottom_right_y:右下角X坐标
 */
printerJobs.prototype.drawbox = function (lineWidth, top_left_x,  top_left_y,  bottom_right_x,  bottom_right_y) {
  var content = "BOX " + top_left_x + " " + top_left_y + " " + bottom_right_x + " " + bottom_right_y + " " + lineWidth + "\r\n";
  this.text(content);
  return this;
};

/**
 *  标签打印 必须在结尾调用
 * @param horizontal 0:正常打印，不旋转；1：整个页面顺时针旋转180°后，打印
 * @param skip       0：打印结束后不定位，直接停止；1：打印结束后定位到标签分割线，如果无缝隙，最大进纸260mm后停止
 */
printerJobs.prototype.label_print = function (horizontal,  skip) {
  var horizontal1;
  var str;
  switch (horizontal) {
    case 0:
      horizontal1 = 0;
      break;
    case 1:
      horizontal1 = 1;
      break;
    case 2:
      horizontal1 = 2;
      break;
    default:
      horizontal1 = 0;
  }

  if (skip == 1) {
    str = "PR " + horizontal1 + "\r\nFORM\r\nPRINT\r\n";
  } else {
    str = "PR " + horizontal1 + "\r\nPRINT\r\n";
  }
  this.text(str);
  return this;
};

/**
 * 打印一维码
 * @param start_x   打印的起始横坐标
 * @param start_y   打印的起始纵坐标
 * @param text      字符串
 * @param type      条码类型
 *                  0：CODE39；1：CODE128；2：CODE93；3：CODEBAR；4：EAN8；5：EAN13；6：UPCA
 *                  ;7:UPC-E;8:ITF
 * @param rotate    旋转角度 0：不旋转；1 旋转
 * @param linewidth 条码宽度
 * @param height    条码高度
 */
printerJobs.prototype.drawBarCode = function (start_x, start_y, text, barcodeType,  rotate,  linewidth,  height) {
	console.log('start_x',start_x)
	console.log('start_y',start_y)
	console.log('text',text)
	console.log('barcodeType',barcodeType)
	console.log('rotate',rotate)
	console.log('linewidth',linewidth)
	console.log('height',height)
  var str1 = "B";
  if (rotate) {
    str1 = "VB";
  }

  var st1 = "128";
  if (barcodeType == 0) {
    st1 = "39";
  } else if (barcodeType == 1) {
    st1 = "128";
  } else if (barcodeType == 2) {
    st1 = "93";
  } else if (barcodeType == 3) {
    st1 = "CODABAR";
  } else if (barcodeType == 4) {
    st1 = "EAN8";
  } else if (barcodeType == 5) {
    st1 = "EAN13";
  } else if (barcodeType == 6) {
    st1 = "UPCA";
  } else if (barcodeType == 7) {
    st1 = "UPCE";
  }

  var content = str1 + " " + st1 + " " + linewidth + " 0 " + height + " " + start_x + " " + start_y + " " + text + "\r\n";
	console.log('content')
	console.log(content)
  this.text(content);
  return this;
};

/**
 * 打印二维码
 * @param start_x 二维码起始位置
 * @param start_y 二维码结束位置
 * @param text    二维码内容
 * @param rotate  旋转角度
 * @param ver     : QrCode宽度(2-15)
 * @param lel     : QrCode纠错等级(0-20)
 */
printerJobs.prototype.drawQrCode = function ( start_x,  start_y,  text,  rotate,  ver,  lel) {
   var str1 = "B";
  if (rotate != 0) {
    str1 = "VB";
  }
  var content = str1 + " QR " + start_x + " " + start_y + " " + " M " + " " + 2 + " " + "U" + " " + ver + " " + "\r\n" + "MA," + text + "\r\n" + "ENDQR" + "\r\n";

  this.text(content);
  return this;
};

/**
     * 打印文字
     *
     * @param text_x    起始横坐标
     * @param text_y    起始纵坐标
     * @param text      字符串
     * @param fontSize  字体大小 20:20点阵 1：16点阵；2：24点阵；3：32点阵；4：24点阵放大一倍；5：32点阵放大一倍
     *                  6：24点阵放大两倍；7：32点阵放大两倍；其他：24点阵
     * @param rotate    旋转角度 0：不旋转；1：90度；2：180°；3:270°
     * @param bold      是否粗体 0：取消；1：设置
     * @param underline 是有有下划线 false:没有；true：有
     * @param reverse   是否反白 false：不反白；true：反白
     */
printerJobs.prototype.drawText = function ( text_x,  text_y,  text,  fontSize,  rotate,  bold,  reverse,  underline) {
  var st1 = "";
  if (rotate == 0) {
    st1 = "T";
  } else if (rotate == 1) {
    st1 = "T90";
  } else if (rotate == 2) {
    st1 = "T180";
  } else if (rotate == 3) {
    st1 = "T270";
  }
   var rev = 0;
   var und = 0;
  if (reverse) {
    rev = 1;
  }
  if (underline) {
    und = 1;
  }
  var st2 = 24;
  var st3 = 0;
  if (fontSize == 20) {
    st2 = 20;
    st3 = 0;
  } else if (fontSize == 1) {
    st2 = 55;
    st3 = 0;
  } else if (fontSize == 2) {
    st2 = 24;
    st3 = 0;
  } else if (fontSize == 3) {
    st2 = 55;
    st3 = 11;
  } else if (fontSize == 4) {
    st2 = 24;
    st3 = 11;
  } else if (fontSize == 5) {
    st2 = 55;
    st3 = 33;
  } else if (fontSize == 6) {
    st2 = 24;
    st3 = 22;
  } else if (fontSize == 7) {
    st2 = 55;
    st3 = 77;
  }
 var content = "SETBOLD " + bold + "\r\n" + "IT " + rev + "\r\n" + "UT " + und + "\r\n" + st1 + " " + st2 + " " + st3 + " " + text_x + " " + text_y + " " + text + "\r\n";

  this.text(content);
  return this;
};

/**
 * 打印反显
 */
printerJobs.prototype.inverse = function ( var1,  var2,  var3,  var4,  width) {
  var str1 = "IL";
  var x0 = var1;
  var y0 = var2;
  var x1 = var3;
  var y1 = var4;
  var w = width;
  if (var1 == var3) {
    x0 = var1;                                                                                                                                           y0 = var2;
    x1 = var1 + width;
    y1 = var2;                                                                                                                          
    w = var4 - var2;
  }
  var content = str1 + " " + x0 + " " + y0 + " " + x1 + " " + y1 + " " + w + "\r\n";

  this.text(content);
  return this;
};

/**
     * 线条
     *
     * @param lineWidth 线条宽度
     * @param start_x   线条起始点x坐标
     * @param start_y   线条起始点y坐标
     * @param end_x     线条结束点x坐标
     * @param end_y     线条结束点y坐标
     * @param fullline  true:实线  false:?虚线
     */
printerJobs.prototype.drawLine = function ( width,  x0,  y0,  x1,  y1) {
  var content = "LINE " + x0 + " " + y0 + " " + x1 + " " + y1 + " " + width + "\r\n";


  this.text(content);
  return this;
};





/**
 * 清空任务
 */
printerJobs.prototype.clear = function() {
	this._queue = Array.from(commands.HARDWARE.HW_INIT);
	return this;
};

/**
 * 返回ArrayBuffer
 */
printerJobs.prototype.buffer = function() {
	return new Uint8Array(this._queue).buffer;
};

export default printerJobs

//module.exports = printerJobs;
